﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Drawing;

namespace MipsPipelineSimulator
{
    class EXStage
    {
        //能否运行
        static public int enableRun = 0;

        static private ManualResetEvent manuaEevent = null;

        static private Thread exThread = null;

        static public Point[] position = new Point[20];

        static private MainForm mainForm = null;

        static public Code code;

        static public object[] args = null;

        static private void ThreadFun()
        {
            if (enableRun < 0)
            {
                manuaEevent.Set();
                return;
            }
            EXStage.enableRun--;

            object obj1 = null;
            string str1 = null;
            string str2 = null;
            string str3 = null;
            string str4 = null;

            switch (code.codeType)
            {
                case CodeType.ADD:
                case CodeType.ADDI:
                    {
                        obj1 = (Int32)EXStage.args[0] + (Int32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.SUB:
                    {
                        obj1 = (Int32)EXStage.args[0] - (Int32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.MUL:
                    {
                        obj1 = (Int32)EXStage.args[0] * (Int32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.SLT:
                case CodeType.SLTI:
                    {
                        obj1 = (Int32)EXStage.args[0] < (Int32)EXStage.args[1] ? 1 : 0;
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.DADD:
                case CodeType.DADDI:
                    {
                        obj1 = (Int64)EXStage.args[0] + (Int64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        break;
                    }
                case CodeType.DSUB:
                    {
                        obj1 = (Int64)EXStage.args[0] - (Int64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        break;
                    }
                case CodeType.AND:
                case CodeType.ANDI:
                    {
                        obj1 = (Int32)EXStage.args[0] & (Int32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.NOR:
                    {
                        obj1 = ~((Int32)EXStage.args[0] | (Int32)EXStage.args[1]);
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.OR:
                case CodeType.ORI:
                    {
                        obj1 = (Int32)EXStage.args[0] | (Int32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.XOR:
                case CodeType.XORI:
                    {
                        obj1 = (Int32)EXStage.args[0] ^ (Int32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.ADD_S:
                    {
                        obj1 = (float)EXStage.args[0] + (float)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Single, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Single, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Single, obj1, "D", false);
                        break;
                    }
                case CodeType.ADD_D:
                    {
                        obj1 = (double)EXStage.args[0] + (double)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Double, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Double, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Double, obj1, "D", false);
                        break;
                    }
                case CodeType.SUB_S:
                    {
                        obj1 = (float)EXStage.args[0] - (float)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Single, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Single, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Single, obj1, "D", false);
                        break;
                    }
                case CodeType.SUB_D:
                    {
                        obj1 = (double)EXStage.args[0] - (double)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Double, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Double, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Double, obj1, "D", false);
                        break;
                    }
                case CodeType.MUL_S:
                    {
                        obj1 = (float)EXStage.args[0] * (float)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Single, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Single, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Single, obj1, "D", false);
                        break;
                    }
                case CodeType.MUL_D:
                    {
                        obj1 = (double)EXStage.args[0] * (double)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Double, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Double, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Double, obj1, "D", false);
                        break;
                    }
                case CodeType.DIV_S:
                    {
                        obj1 = (float)EXStage.args[0] / (float)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Single, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Single, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Single, obj1, "D", false);
                        break;
                    }
                case CodeType.DIV_D:
                    {
                        obj1 = (double)EXStage.args[0] / (double)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Double, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Double, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Double, obj1, "D", false);
                        break;
                    }
                case CodeType.SLLV:
                case CodeType.SLL:
                    {
                        obj1 = (Int32)EXStage.args[0] << (Int32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.SRLV:
                case CodeType.SRL:
                    {
                        obj1 = (Int32)EXStage.args[0] >> (Int32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int32, obj1, "D", false);
                        break;
                    }
                case CodeType.DSLLV:
                case CodeType.DSLL:
                    {
                        obj1 = (Int64)EXStage.args[0] << Convert.ToInt32((Int64)EXStage.args[1]);
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        break;
                    }
                case CodeType.DSRLV:
                case CodeType.DSRL:
                    {
                        obj1 = (Int64)EXStage.args[0] >> Convert.ToInt32((Int64)EXStage.args[1]);
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        break;
                    }
                case CodeType.ADDU:
                case CodeType.ADDIU:
                    {
                        obj1 = (UInt32)EXStage.args[0] + (UInt32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.UInt32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.UInt32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.UInt32, obj1, "D", false);
                        break;
                    }
                case CodeType.SUBU:
                    {
                        obj1 = (UInt32)EXStage.args[0] - (UInt32)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.UInt32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.UInt32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.UInt32, obj1, "D", false);
                        break;
                    }
                case CodeType.SLTU:
                case CodeType.SLTIU:
                    {
                        obj1 = (UInt32)EXStage.args[0] < (UInt32)EXStage.args[1] ? 1 : 0;
                        str1 = CommonTool.NumToStr(TypeCode.UInt32, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.UInt32, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.UInt32, obj1, "D", false);
                        break;
                    }
                case CodeType.DADDU:
                case CodeType.DADDIU:
                    {
                        obj1 = (UInt64)EXStage.args[0] + (UInt64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.UInt64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.UInt64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.UInt64, obj1, "D", false);
                        break;
                    }
                case CodeType.DSUBU:
                    {
                        obj1 = (UInt64)EXStage.args[0] - (UInt64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.UInt64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.UInt64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.UInt64, obj1, "D", false);
                        break;
                    }
                case CodeType.BEQZ:
                case CodeType.BNEZ:
                    {
                        break;
                    }
                case CodeType.LB:
                case CodeType.LH:
                case CodeType.LW:
                case CodeType.LBU:
                case CodeType.LHU:
                case CodeType.LWU:
                case CodeType.LD:
                case CodeType.LDC1:
                case CodeType.LWC1:
                    {
                        obj1 = (Int64)EXStage.args[0] + (Int64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        break;
                    }
                case CodeType.SD:
                    {
                        obj1 = (Int64)EXStage.args[0] + (Int64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        str4 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[2], "D", false);
                        break;
                    }
                case CodeType.SB:
                    {
                        obj1 = (Int64)EXStage.args[0] + (Int64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        str4 = CommonTool.NumToStr(TypeCode.SByte, EXStage.args[2], "D", false);
                        break;
                    }
                case CodeType.SH:
                    {
                        obj1 = (Int64)EXStage.args[0] + (Int64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        str4 = CommonTool.NumToStr(TypeCode.Int16, EXStage.args[2], "D", false);
                        break;
                    }
                case CodeType.SW:
                    {
                        obj1 = (Int64)EXStage.args[0] + (Int64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        str4 = CommonTool.NumToStr(TypeCode.Int32, EXStage.args[2], "D", false);
                        break;
                    }
                case CodeType.SDC1:
                    {
                        obj1 = (Int64)EXStage.args[0] + (Int64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        str4 = CommonTool.NumToStr(TypeCode.Single, EXStage.args[2], "D", false);
                        break;
                    }
                case CodeType.SWC1:
                    {
                        obj1 = (Int64)EXStage.args[0] + (Int64)EXStage.args[1];
                        str1 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[0], "D", false);
                        str2 = CommonTool.NumToStr(TypeCode.Int64, EXStage.args[1], "D", false);
                        str3 = CommonTool.NumToStr(TypeCode.Int64, obj1, "D", false);
                        str4 = CommonTool.NumToStr(TypeCode.Double, EXStage.args[2], "D", false);
                        break;
                    }
            }

            switch (code.codeType)
            {
                case CodeType.ADD:
                case CodeType.SUB:
                case CodeType.MUL:
                case CodeType.SLT:
                case CodeType.DADD:
                case CodeType.DSUB:
                case CodeType.AND:
                case CodeType.NOR:
                case CodeType.OR:
                case CodeType.XOR:
                case CodeType.ADD_S:
                case CodeType.ADD_D:
                case CodeType.SUB_S:
                case CodeType.SUB_D:
                case CodeType.MUL_S:
                case CodeType.MUL_D:
                case CodeType.DIV_S:
                case CodeType.DIV_D:
                case CodeType.SLLV:
                case CodeType.SRAV:
                case CodeType.SRLV:
                case CodeType.DSLLV:
                case CodeType.DSRLV:
                case CodeType.DSRAV:
                case CodeType.ADDU:
                case CodeType.SUBU:
                case CodeType.SLTU:
                case CodeType.DADDU:
                case CodeType.DSUBU:
                    {
                        Thread thread1 = CommonTool.StartDrawPathsThread(new DrawPaths(
                           new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[0],EXStage.position[1],Direction.LeftToRight,str1,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        Thread thread2 = CommonTool.StartDrawPathsThread(new DrawPaths(
                          new Animate[2] { 
                                CommonTool.SetAnimate(EXStage.position[4],EXStage.position[6],Direction.LeftToRight,str2,true,mainForm.GetGraphics()),
                                CommonTool.SetAnimate(EXStage.position[7],EXStage.position[8],Direction.LeftToRight,str2,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        Thread thread3 = CommonTool.StartDrawPathsThread(new DrawPaths(
                           new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[15],EXStage.position[16],Direction.LeftToRight,code.codeType.ToString(),true,mainForm.GetGraphics())
                            }, EXStage.mainForm));

                        thread1.Join();
                        thread1 = null;
                        thread2.Join();
                        thread2 = null;

                        Thread thread4 = CommonTool.StartDrawPathsThread(new DrawPaths(
                          new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[2],EXStage.position[3],Direction.LeftToRight,str3,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        thread3.Join();
                        thread3 = null;
                        thread4.Join();
                        thread4 = null;

                        Thread thread5 = CommonTool.StartBlinkThread(new Blink(
                           str3, EXStage.position[17], DrawTool.blinkTimes, DrawTool.blinkSpanTime, DrawTool.blinkHideTime, EXStage.mainForm));

                        Thread thread6 = CommonTool.StartBlinkThread(new Blink(
                           code.codeType.ToString(), EXStage.position[19], DrawTool.blinkTimes, DrawTool.blinkSpanTime, DrawTool.blinkHideTime, EXStage.mainForm));

                        thread5.Join();
                        thread5 = null;
                        thread6.Join();
                        thread6 = null;

                        CommonTool.DrawPath(EXStage.mainForm,
                           new DrawPath[5]{
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[0],EXStage.position[1]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[4],EXStage.position[6]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[7],EXStage.position[8]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[2],EXStage.position[3]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[15],EXStage.position[16]},DrawTool.orignalPen)
                            });

                        MEMStage.Wait();
                        MEMStage.code = EXStage.code;
                        MEMStage.args = new object[1] {obj1};
                        MEMStage.enableRun++;
                        break;
                    }
                case CodeType.ADDI:
                case CodeType.SLTI:
                case CodeType.DADDI:
                case CodeType.DADDIU:
                case CodeType.ANDI:
                case CodeType.ORI:
                case CodeType.XORI:
                case CodeType.SLL:
                case CodeType.SRA:
                case CodeType.SRL:
                case CodeType.DSLL:
                case CodeType.DSRL:
                case CodeType.DSRA:
                case CodeType.LB:
                case CodeType.LH:
                case CodeType.LW:
                case CodeType.LD:
                case CodeType.LBU:
                case CodeType.LHU:
                case CodeType.LWU:
                case CodeType.LDC1:
                case CodeType.LWC1:
                    {
                        Thread thread1 = CommonTool.StartDrawPathsThread(new DrawPaths(
                           new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[0],EXStage.position[1],Direction.LeftToRight,str1,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        Thread thread2 = CommonTool.StartDrawPathsThread(new DrawPaths(
                          new Animate[4] { 
                                CommonTool.SetAnimate(EXStage.position[13],EXStage.position[14],Direction.LeftToRight,str2,true,mainForm.GetGraphics()),
                                CommonTool.SetAnimate(EXStage.position[14],EXStage.position[9],Direction.BottomToTop,str2,true,mainForm.GetGraphics()),
                                CommonTool.SetAnimate(EXStage.position[9],EXStage.position[10],Direction.LeftToRight,str2,true,mainForm.GetGraphics()),
                                CommonTool.SetAnimate(EXStage.position[7],EXStage.position[8],Direction.LeftToRight,str2,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        Thread thread3 = CommonTool.StartDrawPathsThread(new DrawPaths(
                           new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[15],EXStage.position[16],Direction.LeftToRight,code.codeType.ToString(),true,mainForm.GetGraphics())
                            }, EXStage.mainForm));

                        thread1.Join();
                        thread1 = null;
                        thread2.Join();
                        thread2 = null;

                        Thread thread4 = CommonTool.StartDrawPathsThread(new DrawPaths(
                          new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[2],EXStage.position[3],Direction.LeftToRight,str3,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        thread3.Join();
                        thread3 = null;
                        thread4.Join();
                        thread4 = null;

                        Thread thread5 = CommonTool.StartBlinkThread(new Blink(
                           str3, EXStage.position[17], DrawTool.blinkTimes, DrawTool.blinkSpanTime, DrawTool.blinkHideTime, EXStage.mainForm));

                        Thread thread6 = CommonTool.StartBlinkThread(new Blink(
                           code.codeType.ToString(), EXStage.position[19], DrawTool.blinkTimes, DrawTool.blinkSpanTime, DrawTool.blinkHideTime, EXStage.mainForm));

                        thread5.Join();
                        thread5 = null;
                        thread6.Join();
                        thread6 = null;

                        CommonTool.DrawPath(EXStage.mainForm,
                           new DrawPath[5]{
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[0],EXStage.position[1]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[4]{EXStage.position[13],EXStage.position[14],EXStage.position[9],EXStage.position[10]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[7],EXStage.position[8]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[2],EXStage.position[3]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[15],EXStage.position[16]},DrawTool.orignalPen)
                            });

                        MEMStage.Wait();
                        MEMStage.code = EXStage.code;
                        MEMStage.args = new object[1] { obj1 };
                        MEMStage.enableRun++;
                        break;
                    }
                case CodeType.BEQZ:
                case CodeType.BNEZ:
                    {
                        Thread thread1 = CommonTool.StartDrawPathsThread(new DrawPaths(
                           new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[15],EXStage.position[16],Direction.LeftToRight,code.codeType.ToString(),true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        thread1.Join();
                        thread1 = null;

                        Thread thread2 = CommonTool.StartBlinkThread(new Blink(
                           code.codeType.ToString(), EXStage.position[19], DrawTool.blinkTimes, DrawTool.blinkSpanTime, DrawTool.blinkHideTime, EXStage.mainForm));
                        thread2.Join();
                        thread2 = null;

                        CommonTool.DrawPath(EXStage.mainForm,
                           new DrawPath[1]{
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[15],EXStage.position[16]},DrawTool.orignalPen)
                            });

                        MEMStage.Wait();
                        MEMStage.code = EXStage.code;
                        MEMStage.args = null;
                        MEMStage.enableRun++;
                        break;
                    }
                case CodeType.SD:
                case CodeType.SB:
                case CodeType.SH:
                case CodeType.SW:
                case CodeType.SDC1:
                case CodeType.SWC1:
                    {
                        Thread thread1 = CommonTool.StartDrawPathsThread(new DrawPaths(
                           new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[0],EXStage.position[1],Direction.LeftToRight,str1,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        Thread thread2 = CommonTool.StartDrawPathsThread(new DrawPaths(
                          new Animate[4] { 
                                CommonTool.SetAnimate(EXStage.position[13],EXStage.position[14],Direction.LeftToRight,str2,true,mainForm.GetGraphics()),
                                CommonTool.SetAnimate(EXStage.position[14],EXStage.position[9],Direction.BottomToTop,str2,true,mainForm.GetGraphics()),
                                CommonTool.SetAnimate(EXStage.position[9],EXStage.position[10],Direction.LeftToRight,str2,true,mainForm.GetGraphics()),
                                CommonTool.SetAnimate(EXStage.position[7],EXStage.position[8],Direction.LeftToRight,str2,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        Thread thread3 = CommonTool.StartDrawPathsThread(new DrawPaths(
                           new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[15],EXStage.position[16],Direction.LeftToRight,code.codeType.ToString(),true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        Thread thread7 = CommonTool.StartDrawPathsThread(new DrawPaths(
                           new Animate[3] { 
                                CommonTool.SetAnimate(EXStage.position[4],EXStage.position[5],Direction.LeftToRight,str4,true,mainForm.GetGraphics()),
                                CommonTool.SetAnimate(EXStage.position[5],EXStage.position[11],Direction.TopToBottom,str4,true,mainForm.GetGraphics()),
                                CommonTool.SetAnimate(EXStage.position[11],EXStage.position[12],Direction.LeftToRight,str4,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));

                        thread1.Join();
                        thread1 = null;
                        thread2.Join();
                        thread2 = null;

                        Thread thread4 = CommonTool.StartDrawPathsThread(new DrawPaths(
                          new Animate[1] { 
                                CommonTool.SetAnimate(EXStage.position[2],EXStage.position[3],Direction.LeftToRight,str3,true,mainForm.GetGraphics())
                            }, EXStage.mainForm));
                        thread3.Join();
                        thread3 = null;
                        thread4.Join();
                        thread4 = null;
                        thread7.Join();
                        thread7 = null;

                        Thread thread5 = CommonTool.StartBlinkThread(new Blink(
                           str3, EXStage.position[17], DrawTool.blinkTimes, DrawTool.blinkSpanTime, DrawTool.blinkHideTime, EXStage.mainForm));

                        Thread thread8 = CommonTool.StartBlinkThread(new Blink(
                          str4, EXStage.position[18], DrawTool.blinkTimes, DrawTool.blinkSpanTime, DrawTool.blinkHideTime, EXStage.mainForm));

                        Thread thread6 = CommonTool.StartBlinkThread(new Blink(
                           code.codeType.ToString(), EXStage.position[19], DrawTool.blinkTimes, DrawTool.blinkSpanTime, DrawTool.blinkHideTime, EXStage.mainForm));

                        thread5.Join();
                        thread5 = null;
                        thread6.Join();
                        thread6 = null;
                        thread8.Join();
                        thread8 = null;

                        CommonTool.DrawPath(EXStage.mainForm,
                           new DrawPath[6]{
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[0],EXStage.position[1]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[4]{EXStage.position[13],EXStage.position[14],EXStage.position[9],EXStage.position[10]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[7],EXStage.position[8]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[2],EXStage.position[3]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[2]{EXStage.position[15],EXStage.position[16]},DrawTool.orignalPen),
                                 new DrawPath(mainForm.GetGraphics(),new Point[4]{EXStage.position[4],EXStage.position[5],EXStage.position[11],EXStage.position[12]},DrawTool.orignalPen)
                            });

                        MEMStage.Wait();
                        MEMStage.code = EXStage.code;
                        MEMStage.args = new object[2] {obj1,EXStage.args[2]};
                        MEMStage.enableRun++;
                        break;
                    }
            }
            manuaEevent.Set();                               
        }

        static public void Start(MainForm param)
        {
            mainForm = param;
            //开始标志
            manuaEevent.Reset();
            exThread = new Thread(new ThreadStart(ThreadFun));
            exThread.Start();
        }

        static public void Initialize()
        {
            EXStage.enableRun = -1;
            manuaEevent = new ManualResetEvent(false);
        }

        static public void Wait()
        {
            manuaEevent.WaitOne();
        }

        static public void Close()
        {
            if (exThread != null && exThread.IsAlive)
            {
                exThread.Join();
            }
        }
    }
}
